﻿using MaterialDesignThemes.Wpf;
using NewLife;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using UIWindows.Commands;
using UIWindows.Enums;
using UIWindows.GlobalStatics;
using UIWindows.Models.Devices;
using UIWindows.Tools.Helper;
using UIWindows.Views;
using UIWindows.Views.Dialogs;
using XingLucifer.Devices;
using XingLucifer.IBase;
using XingLucifer.IBase.Enums;

namespace UIWindows.ViewModels
{
    public class RJ6901AViewModel
    {

        public TemporaryStatic Temporary { get; set; }
        public RJ6901AParametersModel RJ6901A { get; set; }
        public DeviceConfigStatic DeviceConfig { get; set; }
        private SystemConfigStatic _systemConfig;
        private UserConfigStatic _userConfig;
        public RJ6901AViewModel(DeviceConfigStatic deviceConfig, SystemConfigStatic systemConfig, UserConfigStatic userConfig, TemporaryStatic temporary)
        {
            DeviceConfig = deviceConfig;
            _systemConfig = systemConfig;
            _userConfig = userConfig;
            Temporary = temporary;
            RJ6901A = new RJ6901AParametersModel { Code = 0 };

            var model = DeviceConfig.RJ6901A.FirstOrDefault(x => x.IsBeingUsed);
            if (model != null)
            {
                model.UpdateValue(RJ6901A);
            }
        }

        public DelegateCommand SendCMD => new DelegateCommand(async () =>
        {
            StringBuilder stringBuilder = new StringBuilder();
            if (RJ6901A.Code != 9999)
            {
                var modeltest = DeviceConfig.RJ6901A.FirstOrDefault(x => x.Code == RJ6901A.Code);
                if (modeltest != null)
                {
                    stringBuilder.Append(RJ6901A.ContrastObject(modeltest));
                }
            }
            byte[] bytes11 = ToBytes(RJ6901A);
            string bl = "true";
            if (!string.IsNullOrEmpty(stringBuilder.ToString()))
            {
                bl = (string)await stringBuilder.ToString().MessageDialogs(MessageLevelType.警告, true, Enums.PopUpTypes.Global, Visibility.Visible);
            }
            if (bl == "true")
            {
                var devices = DeviceConfig.DeviceList.Where(x => x.DeviceType == XingLucifer.IBase.Enums.DeviceTypes.RJ6902R_ShortCircuit);
                StringBuilder error = new StringBuilder();
                _ = DialogHost.Show(new LoadingDialogs(), PopUpTypes.Global.ToString()).ConfigureAwait(false);
                CancellationTokenSource cancellationToken = new CancellationTokenSource();
                await Task.Run(() =>
                {
                    foreach (var x in devices)
                    {
                        if (x.Index == 999 || x.Index == 0 || string.IsNullOrEmpty(x.IPCOM))
                        {
                            return;
                        }
                        byte[] bytes = ToBytes(RJ6901A);
                        try
                        {
                            $"[{x.IPCOM}] [{x.Port}] 执行链接".RunLog(MessageLevelType.信息);
                            ICommunication com = null;
                            if (x.IsSocket)
                            {
                                com = new TCPCom(_systemConfig.SCM.FinsIP, x.IPCOM, x.Port, x.DeviceType, x.Index, x.TaskType, x.ServiceName, cancellationToken, EndianTypes.Modbus_ABCD);
                            }
                            else
                            {
                                com = new SerialPortCom(_systemConfig.SCM.FinsIP, x.IPCOM, x.Port, System.IO.Ports.Parity.None, 8, System.IO.Ports.StopBits.One, x.DeviceType, x.Index, x.TaskType, x.ServiceName, cancellationToken, EndianTypes.Modbus_ABCD);
                            }
                            IDevices model = EquipmentFactory.NewSocketDevice(_systemConfig.SCM.FinsIP, x.IPCOM, x.Port, x.DeviceType, x.Index, x.TaskType, x.ServiceName, cancellationToken, com);
                            if (model == null)
                            {
                                return;
                            }
                            bool? bools = model.Open();
                            if (bools == null || !(bool)bools)
                            {
                                error.AppendLine($"[{x.IPCOM}] [{x.Port}] 设备连接失败,请检查串口服务器!!!");
                                model.Close();
                                return;
                            }
                            //$"[{x.IPCOM}] [{x.Port}]进入波形采集界面".RunLog(MessageLevelType.信息);
                            //if (!SendCommand(com, new byte[] { 0x7B, 0x00, 0x08, 0x02, 0x0F, 0xE1, 0xFA, 0x7D }))
                            //{
                            //    error.AppendLine("进入波形采集界面失败！！！");
                            //    return;
                            //}
                            Thread.Sleep(500);
                            $"[{x.IPCOM}] [{x.Port}]发送设置".RunLog(MessageLevelType.信息);
                            if (!SendCommand(com, bytes))
                            {
                                error.AppendLine("发送设置失败！！！");
                                return;
                            }
                            //Thread.Sleep(200);
                            //$"[{x.IPCOM}] [{x.Port}]采集界面下启动采集命令".RunLog(MessageLevelType.信息);
                            //if (!SendCommand(com, new byte[] { 0x7B, 0x00, 0x08, 0x02, 0x0F, 0xE2, 0xFB, 0x7D }))
                            //{
                            //    error.AppendLine("采集界面下启动采集命令失败！！！");
                            //    return;
                            //}
                            ////Thread.Sleep((int)((RJ6901A.RT * 1000) + 500));
                            //$"[{x.IPCOM}] [{x.Port}]保存采集波形".RunLog(MessageLevelType.信息);
                            //if (!SendCommand(com, new byte[] { 0x7B, 0x00, 0x08, 0x02, 0x0F, 0xE3, 0xFC, 0x7D }))
                            //{
                            //    error.AppendLine("保存采集波形失败！！！");
                            //    return;
                            //}
                            //Thread.Sleep(200);
                            //$"[{x.IPCOM}] [{x.Port}]返回测试界面".RunLog(MessageLevelType.信息);
                            //if (!SendCommand(com, new byte[] { 0x7B, 0x00, 0x08, 0x02, 0x0F, 0x00, 0x19, 0x7D }))
                            //{
                            //    error.AppendLine("返回测试界面失败！！！");
                            //    return;
                            //}
                            model.Close();
                        }
                        catch (Exception ex)
                        {
                            $"[{x.IPCOM}] [{x.Port}]短路测试 配置发送异常{ex}".RunLog(MessageLevelType.错误);
                            error.AppendLine($"[{x.IPCOM}] [{x.Port}] {ex}");
                        }
                    }
                });
                cancellationToken.Cancel();
                _ = $"RJ6901A 测试仪 配置修改：{(string.IsNullOrEmpty(error.ToString()) ? "成功" : "失败,请检测短路仪器是否在测试界面，或是否已解锁！！！")}".MessageDialogs(MessageLevelType.信息, false, Enums.PopUpTypes.Global);
                if (string.IsNullOrEmpty(error.ToString()))
                {
                    RJ6901AParametersModel rj6902remove = DeviceConfig.RJ6901A.FirstOrDefault(x => x.Code == RJ6901A.Code);
                    if (rj6902remove != null)
                    {
                        DeviceConfig.RJ6901A.Remove(rj6902remove);
                    }
                    RJ6901A.UpdateTime = DateTime.Now;
                    RJ6901A.UpdateName = _userConfig.LoginUser.Name;
                    RJ6901A.IsBeingUsed = true;
                    var rj6902r = new RJ6901AParametersModel();
                    RJ6901A.UpdateValue(rj6902r);
                    DeviceConfig.RJ6901A.Insert(0, rj6902r);
                    foreach (var item in DeviceConfig.RJ6901A)
                    {
                        if (item.Code != rj6902r.Code)
                            item.IsBeingUsed = false;
                    }
                    DeviceConfig.SaveRJ6901A();
                    return;
                }
            }
            var model = DeviceConfig.RJ6901A.FirstOrDefault(x => x.IsBeingUsed);
            if (model != null)
            {
                model.UpdateValue(RJ6901A);
            }
            DeviceConfig.SaveRJ6901A();
        }, Enums.AuthorityTypes.工艺_参照);

        public DelegateCommand Empty => new DelegateCommand(() => new RJ6901AParametersModel().UpdateValue(RJ6901A), Enums.AuthorityTypes.工艺_参照);

        public DelegateCommand Delete => new DelegateCommand(async () =>
        {
            var model = DeviceConfig.RJ6901A.FirstOrDefault(x => x.Code == RJ6901A.Code);
            if (model != null
            && (((string)await $"RJ6901A 编号： [{RJ6901A.Code}] 二次确认是否删除".MessageDialogs(MessageLevelType.警告, true, Enums.PopUpTypes.Global, Visibility.Visible)) == "true"))
            {
                DeviceConfig.RJ6901A.Remove(model);
                new RJ6901AParametersModel().UpdateValue(RJ6901A);
                DeviceConfig.SaveRJ6901A();
            }
        }, Enums.AuthorityTypes.工艺_参照);

        public DelegateCommand<RJ6901AParametersModel> MouseDoubleClick => new DelegateCommand<RJ6901AParametersModel>(sender =>
        {
            if (sender == null)
            {
                return;
            }
            sender.UpdateValue(RJ6901A);
        }, Enums.AuthorityTypes.工艺_参照);

        private byte[] ToBytes(RJ6901AParametersModel model)
        {
            //ushort voltage = (ushort)(model.Voltage * 10);
            //ushort rLower = (ushort)(model.RLower * 10);
            //ushort rUpper = (ushort)(model.RUpper * 10);
            //ushort delayTime = (ushort)(model.DelayTime * 10);
            //ushort testTime = (ushort)(model.TestTime * 10);

            var voltageBytes = UShortToBytes((ushort)model.Voltage);
            var delayTimeBytes = UShortToBytes((ushort)(model.DelayTime*10));
            var testTimeBytes = UShortToBytes((ushort)(model.TestTime*10));

            var rLowerBytes = IntToBytes((ushort)(model.RLower*10));
            var rUpperBytes = IntToBytes((ushort)(model.RUpper * 10));



            byte[] bytes = new byte[]{
                0x7B, 0x00, 0x16, 0x02, 0x5A, 0x11,
                (byte)(model.Code >> 8),(byte)model.Code,
                voltageBytes[0],voltageBytes[1],
                delayTimeBytes[0],delayTimeBytes[1],
                testTimeBytes[0],testTimeBytes[1],
                0x00,0x00,
                rLowerBytes[2],rLowerBytes[3],
                rUpperBytes[2],rUpperBytes[3],
                0x72,0x7D
            };
            int be = 0;
            for (int i = 1; i < bytes.Length - 2; i++)
            {
                be += bytes[i];
            }
            bytes[bytes.Length - 2] = (byte)be;
            string hex = BitConverter.ToString(bytes).Replace(" ", " ");
           Debug.WriteLine(hex); // 或者 Debug.WriteLine(hex);
            return bytes;
        }

        private static byte[] UShortToBytes(ushort value)
        {
            byte[] bytes = new byte[2];
            bytes[0] = (byte)(value >> 8);
            bytes[1] = (byte)(value & 0xFF);
            return bytes;
        }

        private static byte[] IntToBytes(int value)
        {
            byte[] bytes = new byte[4];
            bytes[0] = (byte)(value >> 24);
            bytes[1] = (byte)(value >> 16);
            bytes[2] = (byte)(value >> 8);
            bytes[3] = (byte)(value & 0xFF);
            return bytes;
        }

        private static bool SendCommand(ICommunication socket, byte[] bytes)
        {
            socket.Write(bytes);
            System.Threading.Thread.Sleep(50);
            bytes = socket.Read(128);
            if (bytes.Length < 9)
            {
                $"短路测试 协议通信无响应".RunLog(MessageLevelType.错误);
                return false;
            }
            if (bytes[4] != 0x99 && bytes[8] == 0x7d)
            {
                return true;
            }
            string error = null;
            switch (bytes[4])
            {
                case 0x99: error = "校验和错误"; break;
            }
            $"短路测试数值写入异常，错误类型：{error}，返回报文{BitConverter.ToString(bytes)} ".RunLog(MessageLevelType.警告);
            return false;
        }
    }
}
